package com.miracle9.game.server.message;

import com.miracle9.game.bean.DeskSeatBean;
import com.miracle9.game.service.XsManageService;
import com.miracle9.game.service.XxFishService;
import com.miracle9.game.util.GameParameterAssist;
import com.miracle9.game.util.HexUtil;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.*;

import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class MainServer {
    private Logger logger = Logger.getLogger(MainServer.class);
    private static MainServer mainServer = null;
    private SocketAcceptor acceptor = new NioSocketAcceptor();
    private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();

    public static Map<String, IoSession> yjsocket = new ConcurrentHashMap<>();
    public static Map<Integer, DeskSeatBean> timeout = new ConcurrentHashMap<>();
    private int bindPort = 6991;

    @Autowired
    private  XsManageService xsManageService;
    @PostConstruct
    public void init(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                logger.info("xs start .....");
                acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);
                acceptor.getFilterChain().addLast(
                        "codec",
                        new ProtocolCodecFilter(new MyCodecFactory1()));
                acceptor.setHandler(new XsSocketHandler(xsManageService));
                try {
                    acceptor.bind(new InetSocketAddress(bindPort));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                //心跳发送
                while(true){
                    if(!yjsocket.isEmpty()){
                        for (Map.Entry<String, IoSession> entry :  yjsocket.entrySet()) {
                          //  String hex = "FA 16 00 81 6F 13 03 8A 00 00 00 00 00 00 00 00 00 00 00 00 63 FB";
                            String hex = "FA 16 00 81 54 FF 6B 06 00 00 00 00 00 00 00 00 00 00 00 00 51 FB";

                         //   String hex1 = "FA 0C 00 71 01 01 00 00 01 00 7C FB";
                        //    byte[] data = HexUtil.hexStringToByteArray(hex);
                        //    byte[] data1 = HexUtil.hexStringToByteArray(hex1);
                       //     IoBuffer ioBuffer = IoBuffer.allocate(data.length);
                      //      IoBuffer ioBuffer1 = IoBuffer.allocate(data1.length);
                      //      ioBuffer.put(data, 0, data.length);
                       //     ioBuffer.flip();

                     /*       ioBuffer1.put(data1, 0, data1.length);
                            ioBuffer1.flip();*/
                            XsSocketHandler.sendMsg(entry.getValue(),hex);
                          //  entry.getValue().write(ioBuffer);
                        //    entry.getValue().write(ioBuffer1);
                        }
                        try {
                            Thread.sleep(30*1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else {
                        try {
                            Thread.sleep(10*1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }

                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                //超时检测 1 分钟一次
                while(true){
                    if(!XxFishService.userDeskSeatMap.isEmpty()){
                        try {
                            long cur = System.currentTimeMillis();
                            Iterator<Map.Entry<Integer, DeskSeatBean>> iterator = XxFishService.userDeskSeatMap.entrySet().iterator();
                            while(iterator.hasNext()) {
                                Map.Entry<Integer, DeskSeatBean> entry = iterator.next();
                                if(cur - entry.getValue().getDate().getTime() > 120000){
                                    DeskSeatBean deskSeatBean =  entry.getValue();
                                    //触发 长时间未操作 退出房间
                                   /* Map<String, Object> result = new HashMap<>();
                                    result.put("userId", entry.getKey());
                                    result.put("seat", entry.getValue().seat);
                                    result.put("deskId", entry.getValue().getDeskId());
                                    MessageSend.q.notifyAllOperating(new StorageMethodEntity(GameParameterAssist.ba.get(entry.getKey()), "userTimeout", new Object[]{result}));*/

                                    byte[] data = {0x0C, 0x00 ,0x72 ,(byte) deskSeatBean.getSeat(), 0x02,  0x00 , 0x00  ,0x01 ,0x00 };
                                    int sum = calculateChecksum(data);
                                    String jym = Integer.toHexString(sum).toUpperCase();
                                    logger.info("send msg ............msg =  " + "FA 0C 00 72 0"+deskSeatBean.getSeat()+" 02 00 00 01 00 "+jym+" FB");

                                    logger.info("user timeout ticket userID=" +  entry.getKey() + ",seat = " + deskSeatBean.getSeat() + ",device = " + deskSeatBean.getDevice());
                                    IoSession ioSession = MainServer.yjsocket.get(deskSeatBean.getDevice());
                                    if(ioSession!=null){
                                        timeout.put(entry.getValue().getSeat(),entry.getValue());
                                        XsSocketHandler.sendMsg(ioSession,"FA 0C 00 72 0"+deskSeatBean.getSeat()+" 02 00 00 01 00 "+jym+" FB");
                                    }else {
                                        MainServer.yjsocket.remove(deskSeatBean.getDevice());
                                        logger.info("user timeout error ioSession ");
                                    }

                                }
                        }

                            Thread.sleep(30*1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else {
                        try {
                            Thread.sleep(10*1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }).start();
    }

    public static int calculateChecksum(byte[] data) {
        int checksum = 0;
        for (byte b : data) {
            checksum = checksum^b ;
        }
        return checksum;
    }

}

